home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / RTFEDIT.PAK / RTFEDIT.C < prev    next >
C/C++ Source or Header  |  1997-05-06  |  17KB  |  608 lines

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1993-1995  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE:   generic.c
  9. //
  10. //  PURPOSE:   Implement the windows procedure for the main application
  11. //    windows.  Also implement the generic message and command dispatchers.
  12. //
  13. //  FUNCTIONS:
  14. //    WndProc      - Processes messages for the main window.
  15. //    MsgCommand   - Handle the WM_COMMAND messages for the main window.
  16. //    MsgDestroy   - Handles the WM_DESTROY message by calling 
  17. //                   PostQuitMessage().
  18. //    CmdExit      - Handles the file exit command by calling destory 
  19. //                   window on the main window.
  20. //
  21. //  COMMENTS:
  22. //
  23.  
  24. #include <windows.h>            // required for all Windows applications
  25. #include <windowsx.h>
  26. #include <richedit.h>           // For Richedit control
  27. #include <commdlg.h>            // For Richedit control
  28. #include "globals.h"            // prototypes specific to this application
  29. #include "resource.h"
  30.  
  31. HWND        hRTFWnd;
  32. HANDLE      hRTFLib;
  33.  
  34. HWND RTFEDIT_Init(HWND hWndParent); // Function to create RTF Edit control
  35. void RTFEDIT_Shutdown(void);        // Function to housekeep for RTF Edit
  36.  
  37. // Main window message table definition.
  38. MSD rgmsd[] =
  39. {
  40.     {WM_COMMAND, MsgCommand},
  41.     {WM_CREATE,  MsgCreate},
  42.     {WM_DESTROY, MsgDestroy},
  43.     {WM_SIZE,    MsgSize}
  44. };
  45.  
  46. MSDI msdiMain =
  47. {
  48.     sizeof(rgmsd) / sizeof(MSD),
  49.     rgmsd,
  50.     edwpWindow
  51. };
  52.  
  53.  
  54. // Main window command table definition.
  55. CMD rgcmd[] =
  56. {
  57.     {IDM_EXIT,      CmdExit},
  58.     {IDM_ABOUT,     CmdAbout},
  59.     {IDM_BOLD,      RTFEDIT_CmdBold},
  60.     {IDM_ITALIC,    RTFEDIT_CmdItalic},
  61.     {IDM_UNDERLINE, RTFEDIT_CmdUnderline},
  62.     {IDM_FONTS,     RTFEDIT_CmdFonts}
  63. };
  64.  
  65. CMDI cmdiMain =
  66. {
  67.     sizeof(rgcmd) / sizeof(CMD),
  68.     rgcmd,
  69.     edwpWindow
  70. };
  71.  
  72.  
  73. //
  74. //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
  75. //
  76. //  PURPOSE:  Processes messages for the main window.
  77. //
  78. //  PARAMETERS:
  79. //    hwnd     - window handle
  80. //    uMessage - message number
  81. //    wparam   - additional information (dependant on message number)
  82. //    lparam   - additional information (dependant on message number)
  83. //
  84. //  RETURN VALUE:
  85. //    The return value depends on the message number.  If the message
  86. //    is implemented in the message dispatch table, the return value is
  87. //    the value returned by the message handling function.  Otherwise,
  88. //    the return value is the value returned by the default window procedure.
  89. //
  90. //  COMMENTS:
  91. //    Call the DispMessage() function with the main window's message dispatch
  92. //    information (msdiMain) and the message specific information.
  93. //
  94.  
  95. LRESULT CALLBACK WndProc(HWND   hwnd, 
  96.                          UINT   uMessage, 
  97.                          WPARAM wparam, 
  98.                          LPARAM lparam)
  99. {
  100.     return DispMessage(&msdiMain, hwnd, uMessage, wparam, lparam);
  101. }
  102.  
  103.  
  104. //
  105. //  FUNCTION: MsgCommand(HWND, UINT, WPARAM, LPARAM)
  106. //
  107. //  PURPOSE: Handle the WM_COMMAND messages for the main window.
  108. //
  109. //  PARAMETERS:
  110. //    hwnd     - window handle
  111. //    uMessage - WM_COMMAND (Unused)
  112. //    GET_WM_COMMAND_ID(wparam, lparam)   - Command identifier
  113. //    GET_WM_COMMAND_HWND(wparam, lparam) - Control handle
  114. //
  115. //  RETURN VALUE:
  116. //    The return value depends on the message number.  If the message
  117. //    is implemented in the message dispatch table, the return value is
  118. //    the value returned by the message handling function.  Otherwise,
  119. //    the return value is the value returned by the default window procedure.
  120. //
  121. //  COMMENTS:
  122. //    Call the DispCommand() function with the main window's command dispatch
  123. //    information (cmdiMain) and the command specific information.
  124. //
  125.  
  126. #pragma argsused
  127. LRESULT MsgCommand(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  128. {
  129.     return DispCommand(&cmdiMain, hwnd, wparam, lparam);
  130. }
  131.  
  132.  
  133. //
  134. //  FUNCTION: MsgCreate(HWND, UINT, WPARAM, LPARAM)
  135. //
  136. //  PURPOSE: Calls the RTFEDIT_Init function
  137. //
  138. //  PARAMETERS:
  139. //
  140. //    hwnd      - Window handle  (Unused)
  141. //    uMessage  - WM_CREATE
  142. //    wparam    - Extra data     (Unused)
  143. //    lparam    - Extra data     (Unused)
  144. //
  145. //  RETURN VALUE:
  146. //
  147. //    Always returns 0 - Message handled
  148. //
  149. //  COMMENTS:
  150. //
  151. //
  152.  
  153. #pragma argsused
  154. LRESULT MsgCreate(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  155. {
  156.      // Call the RTFEDIT_Init function, which will load the RTF
  157.      // DLL and create the RTF Edit control window.
  158.      hRTFWnd = RTFEDIT_Init(hwnd);
  159.      SetFocus (hRTFWnd);
  160.      return 0;
  161. }
  162.  
  163. //
  164. //  FUNCTION: MsgDestroy(HWND, UINT, WPARAM, LPARAM)
  165. //
  166. //  PURPOSE: Calls PostQuitMessage().
  167. //
  168. //  PARAMETERS:
  169. //
  170. //    hwnd      - Window handle  (Unused)
  171. //    uMessage  - Message number (Unused)
  172. //    wparam    - Extra data     (Unused)
  173. //    lparam    - Extra data     (Unused)
  174. //
  175. //  RETURN VALUE:
  176. //
  177. //    Always returns 0 - Message handled
  178. //
  179. //  COMMENTS:
  180. //
  181. //
  182.  
  183. #pragma argsused
  184. LRESULT MsgDestroy(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  185. {
  186.      RTFEDIT_Shutdown(); // Destroy the RTF Edit control and free the library
  187.      PostQuitMessage(0);
  188.     return 0;
  189. }
  190.  
  191. //
  192. //  FUNCTION: MsgSize(HWND, UINT, WPARAM, LPARAM)
  193. //
  194. //  PURPOSE: Resizes the RTF Edit control
  195. //
  196. //  PARAMETERS:
  197. //
  198. //    hwnd      - Window handle  (Unused)
  199. //    uMessage  - WM_SIZE
  200. //    wparam    - How the window was sized
  201. //    lparam    - MAKELONG (dx,dy)
  202. //
  203. //  RETURN VALUE:
  204. //
  205. //    Always returns 0 - Message handled
  206. //
  207. //  COMMENTS:
  208. //
  209. //
  210.  
  211. #pragma argsused
  212. LRESULT MsgSize(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  213. {
  214.      // Elementary resizing of children to fit in the parent code.
  215.      if (hRTFWnd)
  216.      {
  217.           MoveWindow(hRTFWnd, 0, 0, LOWORD(lparam), HIWORD(lparam), TRUE );
  218.     }
  219.     return 0;
  220. }
  221.  
  222. //
  223. //  FUNCTION: CmdExit(HWND, WORD, WORD, HWND)
  224. //
  225. //  PURPOSE: Exit the application.
  226. //
  227. //  PARAMETERS:
  228. //    hwnd     - The window.
  229. //    wCommand - IDM_EXIT (unused)
  230. //    wNotify  - Notification number (unused)
  231. //    hwndCtrl - NULL (unused)
  232. //
  233. //  RETURN VALUE:
  234. //    Always returns 0 - command handled.
  235. //
  236. //  COMMENTS:
  237. //
  238. //
  239.  
  240. #pragma argsused
  241. LRESULT CmdExit(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  242. {
  243.     DestroyWindow(hwnd);
  244.     return 0;
  245. }
  246.  
  247. //
  248. //  FUNCTION: RTFEDIT_Init(HWND)
  249. //
  250. //  PURPOSE: Register the RTF Edit Class and create the RTF Edit Control Window
  251. //
  252. //  PARAMETERS:
  253. //    hwnd      - Window handle to use for RTF's Parent
  254. //
  255. //  RETURN VALUE:
  256. //
  257. //    On Success: HWND of RTF Edit Control
  258. //    On Failure: NULL
  259. //
  260. //  COMMENTS:
  261. //    This function calls LoadLibrary to load the RTF Edit control
  262. //    DLL (RICHED32.DLL). Make sure to call FreeLibrary (this
  263. //    sample program does it in RTFEDIT_ShutDown).
  264. //
  265. //    A global variable is changed in this function:
  266. //
  267. //      hRTFLib - The handle to the RTF Edit Control DLL
  268. //    
  269.  
  270. HWND RTFEDIT_Init(HWND hWndParent)
  271. {
  272.     HWND       hRTF;
  273.  
  274.     if (!hRTFLib)
  275.       hRTFLib = LoadLibrary("RICHED32.DLL");
  276.  
  277.     if (!hRTFLib)
  278.     {
  279.         char szErr[255];
  280.         wsprintf(szErr, "LoadLibrary Failed. Error Code %ld", GetLastError());
  281.         MessageBox(hWndParent, szErr, szAppName, MB_OK );
  282.         return (hRTFLib = NULL);
  283.     }
  284.  
  285.     hRTF = CreateWindow("RICHEDIT",          // Class Name of RTF Edit
  286.                         "",                  // Text of edit control
  287.                         WS_CHILD       | 
  288.                             WS_VISIBLE | 
  289.                             WS_BORDER  | 
  290.                             ES_MULTILINE,    // Window style
  291.                         0, 0,                // Initially create 0 size,
  292.                         0, 0,                // Main Wnd's WM_SIZE handler will resize
  293.                         hWndParent,          // Use main parent
  294.                         (HMENU)0,            // ID of zero (we don't care)
  295.                         hInst,               // This app instance owns this window
  296.                         NULL                 // Don't need data in WM_CREATE
  297.     );
  298.  
  299.     return hRTF;
  300. }
  301.  
  302. //
  303. //  FUNCTION: RTFEDIT_Shutdown()
  304. //
  305. //  PURPOSE: Destroy the RTF Edit Control and free the RTF DLL.
  306. //
  307. //  PARAMETERS:
  308. //    None
  309. //
  310. //  RETURN VALUE:
  311. //
  312. //    none
  313. //
  314. //  COMMENTS:
  315. //    This function calls FreeLibrary to free the RTF Edit control
  316. //    DLL (RICHED32.DLL). If your application plans on calling this
  317. //    function more than once (in case you have multiple RTF Edit
  318. //    controls), be sure to only call FreeLibrary on the last time.
  319. //    A load count would work fine.
  320. //
  321. //    Two global variables are changed in this function:
  322. //
  323. //      hRTFWnd - The handle to the RTF Edit control in this sample
  324. //      hRTFLib - The handle to the RTF Edit Control DLL
  325. //    
  326.  
  327. void RTFEDIT_Shutdown(void)
  328. {
  329.     if (hRTFWnd) 
  330.     {
  331.         DestroyWindow(hRTFWnd);
  332.         hRTFWnd = NULL;
  333.     }
  334.  
  335.     if (hRTFLib) 
  336.     {
  337.         FreeLibrary(hRTFLib);
  338.         hRTFLib = NULL;
  339.     }
  340. }
  341.  
  342. //
  343. //  FUNCTION: RTFEDIT_CmdBold(HWND, WORD, WORD, HWND)
  344. //
  345. //  PURPOSE: Apply/Remove Bold from text selection
  346. //
  347. //  PARAMETERS:
  348. //    hwnd      - Window handle
  349. //    wCommand  - IDM_BOLD (unused)
  350. //    wNotify   - Notification number (unused)
  351. //    hwndCtrl  - NULL (unused)
  352. //
  353. //  RETURN VALUE:
  354. //
  355. //    Always returns 0 - Message handled
  356. //
  357. //  COMMENTS:
  358. //    This function uses the EM_GETCHARFORMAT and EM_SETCHARFORMAT
  359. //    messages to work with the RTF Edit Control
  360. //
  361.  
  362. #pragma argsused
  363. LRESULT RTFEDIT_CmdBold(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  364. {
  365.     CHARFORMAT cf; // This is defined in RICHEDIT.H
  366.  
  367.     // Version control this structure
  368.     cf.cbSize = sizeof(cf);
  369.  
  370.     // Set the mask to ask the RTF Edit control for the current
  371.     // bold status of the selection (which will be placed
  372.     // in the dwEffects field).
  373.      cf.dwMask      = CFM_BOLD;
  374.  
  375.     // Get the bold status into the CHARFORMAT strucuture,
  376.     // use the selected text. wParam is TRUE to indicate the
  377.     // selected textt, FALSE for the first character in the
  378.     // RTF Edit control.
  379.     SendMessage(hRTFWnd, EM_GETCHARFORMAT, TRUE, (LPARAM)&cf);
  380.  
  381.     // Set the mask to tell the RTF Edit control to pay attention to
  382.     // the bold bit of the dwEffects field.
  383.     cf.dwMask      = CFM_BOLD;
  384.     // Flip da bits
  385.     cf.dwEffects  ^= CFE_BOLD;
  386.  
  387.     // Set the new bold status to the selected text
  388.     SendMessage(hRTFWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
  389.  
  390.     return 0;
  391. }
  392.  
  393. //
  394. //  FUNCTION: RTFEDIT_CmdIatlic(HWND, WORD, WORD, HWND)
  395. //
  396. //  PURPOSE: Apply/Remove Italic from text selection
  397. //
  398. //  PARAMETERS:
  399. //    hwnd      - Window handle
  400. //    wCommand  - IDM_ITALIC (unused)
  401. //    wNotify   - Notification number (unused)
  402. //    hwndCtrl  - NULL (unused)
  403. //
  404. //  RETURN VALUE:
  405. //
  406. //    Always returns 0 - Message handled
  407. //
  408. //  COMMENTS:
  409. //    This function uses the EM_GETCHARFORMAT and EM_SETCHARFORMAT
  410. //    messages to work with the RTF Edit Control
  411. //
  412.  
  413. #pragma argsused
  414. LRESULT RTFEDIT_CmdItalic(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  415. {
  416.     CHARFORMAT cf; // This is defined in RICHEDIT.H
  417.  
  418.     // Version control this structure
  419.     cf.cbSize = sizeof(cf);
  420.  
  421.     // Set the mask to ask the RTF Edit control for the current
  422.     // italic status of the selection (which will be placed
  423.      // in the dwEffects field).
  424.     cf.dwMask      = CFM_ITALIC;
  425.  
  426.     // Get the italic status into the CHARFORMAT strucuture,
  427.     // use the selected text. wParam is TRUE to indicate the
  428.     // selected textt, FALSE for the first character in the
  429.     // RTF Edit control.
  430.     SendMessage(hRTFWnd, EM_GETCHARFORMAT, TRUE, (LPARAM)&cf);
  431.  
  432.     // Set the mask to tell the RTF Edit control to pay attention to
  433.     // the italic bit of the dwEffects field.
  434.     cf.dwMask      = CFM_ITALIC;
  435.     // 'dem bits need a twiddlin'!
  436.      cf.dwEffects  ^= CFE_ITALIC;
  437.  
  438.     // Set the new underline status to the selected text
  439.     SendMessage(hRTFWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
  440.  
  441.     return 0;
  442. }
  443.  
  444. //
  445. //  FUNCTION: RTFEDIT_CmdUnderline (HWND, WORD, WORD, HWND)
  446. //
  447. //  PURPOSE: Apply/Remove Underline from text selection
  448. //
  449. //  PARAMETERS:
  450. //    hwnd      - Window handle
  451. //    wCommand  - IDM_UNDERLINE (unused)
  452. //    wNotify   - Notification number (unused)
  453. //    hwndCtrl  - NULL (unused)
  454. //
  455. //  RETURN VALUE:
  456. //
  457. //    Always returns 0 - Message handled
  458. //
  459. //  COMMENTS:
  460. //    This function uses the EM_GETCHARFORMAT and EM_SETCHARFORMAT
  461. //    messages to work with the RTF Edit Control/
  462. //
  463.  
  464. #pragma argsused
  465. LRESULT RTFEDIT_CmdUnderline(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  466. {
  467.     CHARFORMAT cf; // This is defined in RICHEDIT.H
  468.  
  469.     // Version control this structure
  470.     cf.cbSize = sizeof(cf);
  471.  
  472.     // Set the mask to ask the RTF Edit control for the current
  473.     // underline status of the selection (which will be placed
  474.      // in the dwEffects field).
  475.     cf.dwMask      = CFM_UNDERLINE;
  476.  
  477.  
  478.     // Get the underline status into the CHARFORMAT strucuture,
  479.     // use the selected text. wParam is TRUE to indicate the
  480.     // selected textt, FALSE for the first character in the
  481.     // RTF Edit control.
  482.     SendMessage(hRTFWnd, EM_GETCHARFORMAT, TRUE, (LPARAM)&cf);
  483.  
  484.     // Set the mask to tell the RTF Edit control to pay attention to
  485.     // the underline bit of the dwEffects field.
  486.     cf.dwMask      = CFM_UNDERLINE;
  487.      // Twiddle de bits, captain!
  488.     cf.dwEffects  ^= CFE_UNDERLINE;
  489.  
  490.     // Set the new underline status to the selected text
  491.     SendMessage(hRTFWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
  492.  
  493.     return 0;
  494. }
  495.  
  496. //
  497. //  FUNCTION: RTFEDIT_CmdFonts (HWND, WORD, WORD, HWND)
  498. //
  499. //  PURPOSE: Allow use to change font of selected text
  500. //
  501. //  PARAMETERS:
  502. //    hwnd      - Window handle
  503. //    wCommand  - IDM_FONTS (unused)
  504. //    wNotify   - Notification number (unused)
  505. //    hwndCtrl  - NULL (unused)
  506. //
  507. //  RETURN VALUE:
  508. //
  509. //    Always returns 0 - Message handled
  510. //
  511. //  COMMENTS:
  512. //    This function uses the EM_GETCHARFORMAT and EM_SETCHARFORMAT
  513. //    messages to work with the RTF Edit Control
  514. //    
  515.  
  516. #pragma argsused
  517. LRESULT RTFEDIT_CmdFonts(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  518. {
  519.     CHARFORMAT cf;                // This is defined in RICHEDIT.H
  520.     CHOOSEFONT ChooseFontStruct;  // Common Dialog fun
  521.     LOGFONT    lf;                // Log font information
  522.     HDC        hDC;
  523.  
  524.     // Version control this structure
  525.     cf.cbSize = sizeof(cf);
  526.  
  527.     // Get the font formatting status into the CHARFORMAT strucuture,
  528.     // use the selected text. wParam is TRUE to indicate the
  529.     // selected text, FALSE for the first character in the
  530.      // RTF Edit control.
  531.     SendMessage(hRTFWnd, EM_GETCHARFORMAT, TRUE, (LPARAM)&cf);
  532.  
  533.     // Fill in the font info for the font common fialog
  534.  
  535.     memset(&ChooseFontStruct, 0, sizeof(CHOOSEFONT));
  536.     memset(&lf, 0, sizeof(LOGFONT));
  537.  
  538.     hDC = GetDC(hwnd); // Need a screen DC, use the parent's DC
  539.  
  540.     // The RTF Edit control measures in twips. Each point is
  541.     // 20 twips.
  542.  
  543.      lf.lfHeight = cf.yHeight/-20;
  544.  
  545.     // Set up the rest of the logfont structure according to the 
  546.     // information retrieved from the EM_GETCHARFORMAT message
  547.  
  548.     if (cf.dwEffects & CFE_BOLD)
  549.         lf.lfWeight = FW_BOLD;
  550.     else
  551.           lf.lfWeight = FW_NORMAL;
  552.      #pragma warn -sig
  553.      lf.lfItalic = (BOOL)(cf.dwEffects & CFE_ITALIC);
  554.      lf.lfUnderline = (BOOL)(cf.dwEffects & CFE_UNDERLINE);
  555.      #pragma warn .sig
  556.      lf.lfCharSet = DEFAULT_CHARSET;
  557.     lf.lfQuality = DEFAULT_QUALITY;
  558.      lf.lfPitchAndFamily = cf.bPitchAndFamily;
  559.     lstrcpy(lf.lfFaceName, cf.szFaceName);
  560.  
  561.     // Fire up the common dialog.
  562.  
  563.     ChooseFontStruct.lStructSize = sizeof(ChooseFontStruct);
  564.     ChooseFontStruct.hwndOwner = hwnd;
  565.     ChooseFontStruct.hDC = hDC;
  566.     ChooseFontStruct.lpLogFont = &lf;
  567.     ChooseFontStruct.Flags = CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT;
  568.     ChooseFontStruct.rgbColors = RGB(0,0,0);
  569.     ChooseFontStruct.nFontType = SCREEN_FONTTYPE;
  570.  
  571.      if (ChooseFont(&ChooseFontStruct))
  572.     {
  573.         // Set the mask to tell the RTF Edit control to pay attention to
  574.         // the font formatting bits.
  575.         cf.dwMask = CFM_BOLD | CFM_FACE | CFM_ITALIC | 
  576.                     CFM_OFFSET | CFM_SIZE | CFM_UNDERLINE;
  577.  
  578.         //  Undo the equation from above.
  579.  
  580.         cf.yHeight = lf.lfHeight * -20;
  581.  
  582.         // Fill in the rest of the characater formatting
  583.          
  584.           cf.dwEffects = 0;
  585.         if (FW_BOLD == lf.lfWeight)
  586.             cf.dwEffects |= CFE_BOLD;
  587.         if (lf.lfItalic)
  588.             cf.dwEffects |= CFE_ITALIC;
  589.  
  590.         if (lf.lfUnderline)
  591.             cf.dwEffects |= CFE_UNDERLINE;
  592.  
  593.         cf.bPitchAndFamily = lf.lfPitchAndFamily;
  594.  
  595.         lstrcpy(cf.szFaceName, lf.lfFaceName);
  596.  
  597.           // Set the new formatting to the selected text
  598.         SendMessage(hRTFWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
  599.     }
  600.  
  601.     // Don't forget this!
  602.     ReleaseDC(hwnd, hDC);
  603.  
  604.     return 0L;
  605. }
  606.  
  607.  
  608.